import { select, selectAll } from 'd3-selection'
import { recursiveTreeValue } from '../utils'

let currentMarkIcon = null

export function graphNodeMarkers (nodeContainer, skeletonTheme) {
  nodeContainer
    .selectAll('.xmind-node-mark')
    .remove()
  const enter = nodeContainer
    .selectAll('.x-mind-nodetheme')
    .filter(node => node.data.marks?.length)
    .append('g')
    .attr('class', 'xmind-node-mark')
    .attr('transform', 'translate(0, 0)')

  const childEnter = enter
    .selectAll('g')
    .data(d => (d.data.marks || []).map((o, i) => {
      return {
        ...o,
        _id: d.data._id,
        x: d.x,
        y: d.y,
        height: d.height,
        style: d.style,
        sortIdx: i,
        marks: d.data.marks,
        foreignObjectHeight: d.data.foreignObjectHeight,
        isTask: d.data.isTask,
        tagLineHeight: d.tagLineHeight
      }
    }))
    .enter()
    .append('g')
    .on('mouseenter', function () {
      select(this).raise()
    })
    .on('mouseleave', function () {
      select(this.parentNode).selectAll('g').sort((a, b) => a.sortIdx - b.sortIdx)
    })
    .on('click', function (event) {
      markHandlerClick(event, this, skeletonTheme)
    })

  childEnter.append('circle')
    .attr('cx', (d, i) => {
      const taskSpacing = d.isTask ? d.style.linkSize + 8 : 0
      return d.x + d.style.margin._l + i * d.style.markSize * 0.85 + d.style.markSize / 2 + taskSpacing
    })
    .attr('cy', d => d.y + d.height - d.foreignObjectHeight / 2 - d.style.margin._b - d.tagLineHeight)
    .attr('r', d => d.style.markSize / 2 + 2)
    .attr('fill', '#fff')

  childEnter.append('rect')
    .attr('x', (d, i) => {
      const taskSpacing = d.isTask ? d.style.linkSize + 8 : 0
      return d.x + d.style.margin._l + i * d.style.markSize * 0.85 - 2 + taskSpacing
    })
    .attr('y', d => d.y + d.height - (d.foreignObjectHeight + d.style.markSize) / 2 - d.style.margin._b - d.tagLineHeight - 2)
    .attr('width', d => d.style.markSize + 4)
    .attr('height', d => d.style.markSize + 4)
    .attr('fill', 'transparent')
    .attr('rx', 2)
    .attr('ry', 2)
    .attr('stroke-width', 2)
    .attr('stroke', 'transparent')

  childEnter
    .append('svg')
    .attr('viewBox', '0, 0, 1024, 1024')
    .attr('width', d => d.style.markSize)
    .attr('height', d => d.style.markSize)
    .attr('x', (d, i) => {
      const taskSpacing = d.isTask ? d.style.linkSize + 8 : 0
      return d.x + d.style.margin._l + i * d.style.markSize * 0.85 + taskSpacing
    })
    .attr('y', d => d.y + d.height - (d.foreignObjectHeight + d.style.markSize) / 2 - d.style.margin._b - d.tagLineHeight)
    .html(d => {
      return select(`#${d.icon}`).node().innerHTML
    })
}

export function markHighLight (_this, skeletonTheme) {
  select(_this)
    .classed('mark-select', true)
    .select('rect')
    .attr('stroke', skeletonTheme.select.stroke)
}

export function removeMarkHighlight () {
  selectAll('.mark-select')
    .classed('mark-select', false)
    .select('rect')
    .attr('stroke', 'transparnet')
}

function markHandlerClick (event, _this, skeletonTheme) {
  event.stopPropagation()
  const data = select(_this).datum()
  removeMarkHighlight()
  markHighLight(_this, skeletonTheme)
  currentMarkIcon = data
}

export function deleteIconMark (root, callback) {
  if (!currentMarkIcon) return
  const { marks, icon } = currentMarkIcon
  const idx = marks.findIndex(m => m.icon === icon)
  marks.splice(idx, 1)
  recursiveTreeValue(root, currentMarkIcon._id, 'marks', marks)
  callback && callback()
  currentMarkIcon = null
}
